package com.neusoft.neuiotms.dcom.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityNotFoundException;
import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.web.bean.TreeBean;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.bizcore.web.utils.BuildTreeUtil;
import com.neusoft.neuiotms.dcom.converter.KnowledgeTypeConverter;
import com.neusoft.neuiotms.dcom.dto.KnowledgeDTO;
import com.neusoft.neuiotms.dcom.dto.KnowledgeTypeDTO;
import com.neusoft.neuiotms.dcom.model.KnowledgeType;
import com.neusoft.neuiotms.dcom.repository.KnowledgeTypeRepository;
import com.neusoft.neuiotms.dcom.service.KnowledgeService;
import com.neusoft.neuiotms.dcom.service.KnowledgeTypeService;

@Service
public class KnowledgeTypeServiceImpl implements KnowledgeTypeService {

    @Autowired
    private KnowledgeTypeRepository knowledgeTypeRepository;

    @Autowired
    private KnowledgeTypeConverter knowledgeTypeConverter;

    //    @Autowired
    //    private ProductService productService;

    @Autowired
    private KnowledgeService knowledgeService;

    @Override
    public List<KnowledgeTypeDTO> findAll() {
        final List<KnowledgeType> knowledgeType = this.knowledgeTypeRepository.findAll();
        return this.knowledgeTypeConverter.toListDTO(knowledgeType);
    }

    @Override
    public Page<KnowledgeTypeDTO> search(final Pageable pageable, final Searchable searchable) {
        final Page<KnowledgeType> models = this.knowledgeTypeRepository.search(pageable, searchable);
        return this.knowledgeTypeConverter.toPageDTO(models);
    }

    @Override
    @Transactional
    public KnowledgeTypeDTO create(final KnowledgeTypeDTO dto) {
        final KnowledgeType knowledgeType = this.knowledgeTypeRepository.findByCode(dto.getCode());
        if (knowledgeType != null) {
            throw new UnitedException("已存在", new Object[] {});
        }

        final KnowledgeType model = this.knowledgeTypeConverter.toModel(dto);
        this.knowledgeTypeRepository.save(model);

        //知识关系迁移处理
        //        if (dto.getParentId() != null) {
        //            final List<KnowledgeType> list = this.knowledgeTypeRepository.findByParentId(dto.getParentId());
        //            if (CollectionUtils.isNotEmpty(list) && (list.size() == 1)) {
        //                
        //                final List<Knowledge> knowledgeList = this.knowledgeService.findByType(model.getParent());
        //                knowledgeList.stream().forEach(l -> {
        //                    l.setType(model);
        //                });
        //                this.knowledgeRepository.saveAll(knowledgeList);
        //            }
        //        }
        return this.knowledgeTypeConverter.toDTO(model);
    }

    @Override
    public KnowledgeTypeDTO update(final Long id, final KnowledgeTypeDTO dto) {
        final KnowledgeType knowledgeType = this.knowledgeTypeRepository.findByCode(dto.getCode());
        if ((knowledgeType != null) && (!knowledgeType.getId().equals(id))) {
            throw new UnitedException("已存在", new Object[] {});
        }
        KnowledgeType model;
        try {
            model = this.knowledgeTypeRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException("知识类型不存在!", new Object[] {id });
        }

        dto.setId(model.getId());
        model = this.knowledgeTypeConverter.toModel(dto);
        this.knowledgeTypeRepository.save(model);
        return this.knowledgeTypeConverter.toDTO(model);
    }

    @Override
    public KnowledgeTypeDTO details(final Long id) {
        final KnowledgeType model;
        try {
            model = this.knowledgeTypeRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException("知识类型不存在!", new Object[] {id });
        }
        return this.knowledgeTypeConverter.toDTO(model);
    }

    @Override
    public void delete(final Long code) {
        final KnowledgeType model;
        try {
            model = this.knowledgeTypeRepository.getOne(code);
        } catch (final EmptyResultDataAccessException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {code });
        }

        final List<KnowledgeType> models = this.knowledgeTypeRepository.findByParentId(model.getId());

        if ((models != null) && !models.isEmpty()) {
            throw new UnitedException("知识分类存在下级类型，请先删除下级知识类型", new Object[] {code });
        }

        //        final List<ProductDTO> productList = this.productService.findByAssetType(model);
        //        if ((productList != null) && !productList.isEmpty()) {
        //            throw new UnitedException("该类型下已有产品，请先删除产品", new Object[] {id });
        //        }

        //        final List<Knowledge> assetList = this.knowledgeService.findByType(model);
        final Searchable searchable = new Searchable();
        searchable.put("knowledgeType", code);
        final List<KnowledgeDTO> knowledges = this.knowledgeService.index(searchable);
        if (knowledges.size() > 0) {
            throw new UnitedException("知识分类已有，请先删除", new Object[] {code });
        }

        //        if ((knowledges != null) && !knowledges.isEmpty()) {
        //            throw new UnitedException("该类型下已有资产，请先删除资产", new Object[] {code });
        //        }

        try {
            this.knowledgeTypeRepository.deleteById(code);
        } catch (final EmptyResultDataAccessException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {code });
        }

    }

    @Override
    public List<TreeBean> tree() {
        final Sort sort = new Sort(Direction.ASC, "sort");
        final List<KnowledgeType> knowledgeType = this.knowledgeTypeRepository.findAll(sort);
        final List<TreeBean> tree = new ArrayList<>();
        knowledgeType.forEach(type -> {
            final TreeBean bean = new TreeBean();
            bean.setCode(type.getCode());
            bean.setTitle(type.getName());
            final Map<String, Object> attr = new HashMap<>();
            attr.put("id", type.getId());
            attr.put("parentId", type.getParent() == null ? "-1" : type.getParent().getId());
            attr.put("sort", type.getSort());
            //            attr.put("measureUnit", type.getMeasureUnit());
            bean.setAttr(attr);
            tree.add(bean);
        });
        return new BuildTreeUtil(tree).buildTree();
    }

}
